﻿#pragma once
#include "XyNetCompiler/Service.h"
#include <boost/property_tree/ptree.hpp>

namespace XyNet
{
	class CodeGenerator;

	/// 服务解析器
	class ServiceParser
	{
	public:
		/// 添加代码生成器
		void addCodeGenerator(shared_ptr<CodeGenerator> codeGenerator);

		/// 获取服务文件路径
		const filesystem::path& getServiceFilePath() const;
		/// 获取导入列表
		const vector<string>* getImports() const;
		/// 获取包
		const string& getPackage() const;
		/// 获取服务列表
		const vector<Service>* getServices() const;
		/// 获取错误映射
		const map<string, Error>* getErrors() const;
		/// 查找错误
		const Error* findError(const string& errorName);

		/// 解析服务文件
		void parse(const filesystem::path& serviceFilePath);

		/// 解析错误
		void parseError(const boost::property_tree::ptree& errorTree);
		/// 解析服务
		void parseService(Service* service, const boost::property_tree::ptree& serviceTree);
		/// 解析方法
		void parseMethod(Method* method, const boost::property_tree::ptree& methodTree);
		/// 解析方法请求应答
		void parseMethodRequestResponse(
			vector<pair<string, string>>* requestResponseArguments,
			const boost::property_tree::ptree& requestResponseTree);
		/// 解析方法错误
		void parseMethodError(
			vector<Error>* methodErrors, const boost::property_tree::ptree& methodErrorTree);

	private:
		vector<shared_ptr<CodeGenerator>> _codeGenerators;

		filesystem::path _serviceFilePath;
		boost::property_tree::ptree _tree;

		vector<string> _imports;
		string _package;	// 只允许一个命名空间
		vector<Service> _services;
		map<string, Error> _errors;
	};
}